using System;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using System.Web.Security;
using Castle.MonoRail.Framework;
using WineCellar.Web;
using WineCellar.Web.Common;

namespace WineCellar.Web.Filters
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class AuthenticationFilterAttribute : FilterAttribute
    {
        private string[] _allowedRoles;
        public string[] AllowedRoles
        {
            get
            {
                return this._allowedRoles;
            }
            set
            {
                this._allowedRoles = value;
            }
        }

        public AuthenticationFilterAttribute(string[] allowedRoles)
			: base(ExecuteWhen.BeforeAction, typeof(AuthenticationFilterImpl))
        {
            this._allowedRoles = allowedRoles;
        }
        public AuthenticationFilterAttribute()
			: base(ExecuteWhen.BeforeAction, typeof(AuthenticationFilterImpl))
        {

        }
    }
    public class AuthenticationFilterImpl : IFilter, IFilterAttributeAware
    {
        private AuthenticationFilterAttribute _attribute;
        #region IFilter Members

        public bool Perform(ExecuteWhen exec, IEngineContext context, IController controller,IControllerContext controllerContext)
        {

            RolePrincipal principal = SecurityHelper.GetCurrentUser(context);
            MembershipManagerSection membershipManagerSection = MembershipManagerSection.GetConfig();

            bool isPermitted = false;

            if (principal == null ||
                !principal.Identity.IsAuthenticated) //Redirect to Login
            {
                OrderedDictionary parameters = new OrderedDictionary();
                parameters.Add("returnUrl", context.UrlInfo.Controller + "/" + context.UrlInfo.Action);	
				context.Response.Redirect
					(membershipManagerSection.Links.LoginController,membershipManagerSection.Links.LoginAction, parameters);
            }
            else
            {
                if (this._attribute.AllowedRoles != null)
                {
                    foreach (string allowedRole in this._attribute.AllowedRoles)
                        isPermitted = isPermitted || (principal.IsInRole(allowedRole));
                    if (!isPermitted)
                    {
                        context.Response.Redirect
							(membershipManagerSection.Links.LoginController,membershipManagerSection.Links.LoginAction);						
                    }
                }
                else
                    isPermitted = true;
            }

            return isPermitted;
        }
        
		private string GetFullPath(IController controller, string relativeUrl)
        {
            Regex appPathRemoveSlash = new Regex(@"(?<value>([\w:/.])+[^/])[/]*$");
            Regex relativeUrlRemoveSplash = new Regex(@"/*(?<value>\S+)");
			return appPathRemoveSlash.Match(((Controller)controller).Context.ApplicationPath).Groups["value"].Value + '/' +
                relativeUrlRemoveSplash.Match(relativeUrl).Groups["value"].Value;
        }


        #endregion

        #region IFilterAttributeAware Members

        public FilterAttribute Filter
        {
            set { this._attribute = (AuthenticationFilterAttribute)value; }
        }

        #endregion        
    }
}
